package lookas;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Random;

import lookas.dao.SimpleDao;

import org.apache.commons.collections15.Bag;
import org.apache.commons.collections15.bag.HashBag;

public class NamesGenerator{

    private static final String FIRST_SUM   = "select sum(licznosc) from imiona";
    private static final String SECOND_SUM  = "select sum(licznosc) from nazwiska";
    private static final String FIRSTNAME   = "select imie, licznosc from imiona where licznosc>0";
    private static final String SECONDNAME  = "select nazwisko, licznosc from nazwiska where licznosc>0";

    private int                 probeSize   = 100;
    private Bag<String>         firstNames  = new HashBag<String>();
    private Bag<String>         secondNames = new HashBag<String>();

    private long                firstSize;
    private long                secondSize;

    public String nextFirstName(){
        if(firstNames.size() == 0){
            firstNames = run(firstSize, probeSize, FIRSTNAME);
        }
        String next = firstNames.iterator().next();
        firstNames.remove(next);
        return next;
    }

    public String nextSecondName(){
        if(secondNames.size() == 0){
            secondNames = run(secondSize, probeSize, SECONDNAME);
        }
        String next = secondNames.iterator().next();
        secondNames.remove(next);
        return next;
    }

    public NamesGenerator(){
        firstSize = getSize(FIRST_SUM);
        secondSize = getSize(SECOND_SUM);
    }

    private static long getSize(String sql){
        try{
            Connection con = SimpleDao.getConnection();
            PreparedStatement stmt;
            ResultSet res;
            stmt = con.prepareStatement(sql);
            res = stmt.executeQuery();
            long N = 0;
            if(res.next()){
                N = res.getLong(1);
            }
            stmt.close();
            con.close();
            return N;
        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }

    private Bag<String> run(long size, int n, String sql){
        Connection con = null;
        try{
            int k = (int)(size / n);

            Bag<String> ret = new HashBag<String>();

            con = SimpleDao.getConnection();
            PreparedStatement stmt;
            ResultSet res;
            stmt = con.prepareStatement(sql);
            res = stmt.executeQuery();
            int sum = 0;
            int next = new Random().nextInt(k);
            while(res.next()){
                int value = res.getInt(2);
                sum += value;
                while(next < sum){
                    String name = res.getString(1);
                    ret.add(name);
                    if(ret.size() == n)
                        return ret;
                    next += k;
                }
            }
            stmt.close();

            return ret;
        }catch(Exception e){
            throw new RuntimeException(e);
        }finally{
            try{
                con.close();
            }catch(SQLException e){}
        }
    }

    public void setProbeSize(int probeSize){
        this.probeSize = probeSize;
    }
}
